package com.telit.web.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.telit.common.constant.MsgConstants;
import com.telit.common.constant.MsgIdentificationConstants;
import com.telit.common.constant.NoticeTypeConstants;
import com.telit.common.entity.DataReturn;
import com.telit.common.enums.ResultCode;
import com.telit.common.pojo.AliPushContentPojo;
import com.telit.common.pojo.AliPushMessagePojo;
import com.telit.common.util.AliyunPushMessageUtils;
import com.telit.communicate.dto.SendMessageDTO;
import com.telit.communicate.feign.RemoteCommunicateService;
import com.telit.web.domain.pojo.AliVideoPojo;
import com.telit.web.domain.vo.AndroidHangOffVO;
import com.telit.web.domain.vo.WebHangOffVO;
import com.telit.web.dto.AppVideoDTO;
import com.telit.web.service.AliVideoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;


/**
 * @Auther amy
 * @Describe 阿里云音视频消息
 */
@RestController
@RequestMapping("/ali_video")
@Api(tags = "阿里音视频通话", description = "/ali_video")
@RefreshScope
public class AliVideoController {

    private static Logger logger = LoggerFactory.getLogger(AliVideoController.class);

    @Value("${aliyun.video.appId}")
    private String appId;

    @Value("${aliyun.video.appKey}")
    private String appKey;

    @Value("${aliyun.video.gslb}")
    private String gslb;

    @Autowired
    private RemoteCommunicateService communicateClient;

    @Autowired
    private AliVideoService aliVideoService;

    @PostMapping(value = "/pushAliToken", produces = "application/json;charset=UTF-8")
    @ApiOperation("推送token,将阿里云的参数给到安卓端")
    public DataReturn pushAliToken(@Validated @RequestBody AliVideoPojo pojo) {
        try {
            List<Map<String, String>> protectorDataList = pojo.getProtectorDataList();
            // 为了app端视频通话获取token
            AppVideoDTO appResult = null;
            if (!CollectionUtils.isEmpty(protectorDataList)) {
                // 时间戳
                String timestamp = String.valueOf(System.currentTimeMillis() + 48 * 60 * 60 * 60 * 1000);
                // 用户id集合
                Set<String> protectorIdList = new HashSet<>();
                for (Map<String, String> protectorDataMap : protectorDataList) {
                    String userId = protectorDataMap.get("userId");
                    if (StringUtils.isEmpty(userId)) {
                        continue;
                    }
                    String nonce =
                            "AK-" + new UUID(RandomUtils.nextLong(), RandomUtils.nextLong()).toString().replace("-",
                                    "");
                    protectorDataMap.put("nonce", nonce);
                    String token = aliVideoService.createToken(timestamp, userId, pojo.getChannelId(), nonce);
                    protectorDataMap.put("token", token);
                    protectorIdList.add(userId);

                }
                pojo.setAppId(appId);
                pojo.setAppKey(appKey);
                pojo.setTimestamp(timestamp);
                pojo.setGslb(gslb);
                pojo.setPushDate(new Date());

                //推送给安卓
                if (!CollectionUtils.isEmpty(protectorIdList)) {
                    AliPushMessagePojo aliPushMessagePojo = AliPushMessagePojo.builder().accountList(
                            new ArrayList<>(protectorIdList))
                            .deviceType(MsgConstants.DEVICE_TYPE_ANDROID)
//                            .pushType(MsgConstants.PUSH_TYPE_NOTICE)
                            .pushType(MsgConstants.PUSH_TYPE_MESSAGE)
                            .target(MsgConstants.TARGET_ACCOUNT)
                            .title("通话通知")
                            .pushContentPojo(new AliPushContentPojo(NoticeTypeConstants.NOTICE_TYPE_CALL,
                                    JSON.toJSONString(pojo)))
                            .build();
                    AliyunPushMessageUtils.customizeAdvancedPush(aliPushMessagePojo);

                    // 推送指定的web端
                    communicateClient.sendMsg(new SendMessageDTO("special", protectorIdList.toArray(new String[0]),
                            JSONObject.toJSONString(DataReturn.ok(MsgIdentificationConstants.START_MEETING, pojo))));
                }

                // 生成app端发起人相应的token
                if (StringUtils.hasText(pojo.getFromUserId())) {
                    appResult = aliVideoService.getAppSimpleTokenInfo(timestamp, pojo.getFromUserId(),
                            pojo.getChannelId(),
                            "AK-" + new UUID(RandomUtils.nextLong(), RandomUtils.nextLong()).toString().replace("-",
                                    ""));
                }
            }
            return DataReturn.ok(appResult);
        } catch (Exception e) {
            logger.error("推送token失败,e:{}", e);
            return DataReturn.failure(ResultCode.SERVER_ERROR, e.getMessage());
        }
    }

    @PostMapping(value = "/hangOff", produces = "application/json;charset=UTF-8")
    @ApiOperation("会议取消,房主的挂断才会调用此接口,通知其他人参会人员都挂断")
    public DataReturn hangOff(@RequestBody WebHangOffVO webHangOffVO) {
        try {
            Map<String, Object> pushMap = new HashMap<String, Object>();
            pushMap.put("message", "hangOff");
            pushMap.put("pushDate", new Date());
            pushMap.put("channel", webHangOffVO.getChannel());

            // app端挂断电话消息推送
            hangOffPushAliYunMsg(webHangOffVO.getProtectorIdList(), JSON.toJSONString(pushMap));

            // 推送web端
            if (!CollectionUtils.isEmpty(webHangOffVO.getProtectorIdList())) {
                communicateClient.sendMsg(
                        new SendMessageDTO("special", webHangOffVO.getProtectorIdList().toArray(new String[0]),
                                JSONObject.toJSONString(
                                        DataReturn.ok(MsgIdentificationConstants.CANCEL_MEETING, pushMap))));
            }
            return DataReturn.ok();
        } catch (Exception e) {
            logger.error("会议取消接口调用失败,e:{}", e);
            return DataReturn.failure(ResultCode.SERVER_ERROR, e.getMessage());
        }
    }

    @PostMapping(value = "/androidHangOff", produces = "application/json;charset=UTF-8")
    @ApiOperation("安卓端会议取消")
    public DataReturn androidHangOff(@RequestBody AndroidHangOffVO androidHangOffVO) {
        Set<String> accountIdList = androidHangOffVO.getProtectorIdList();
        try {
            if ("app".equals(androidHangOffVO.getResource())) {
                Map<String, Object> pushMap = new HashMap<String, Object>();
                pushMap.put("message", "hangOff");
                pushMap.put("pushDate", new Date());
                pushMap.put("channel", androidHangOffVO.getChannel());
                // 通知app端挂断电话
                hangOffPushAliYunMsg(androidHangOffVO.getProtectorIdList(), JSON.toJSONString(pushMap));
            } else {
                // 默认通知web端挂断电话
                if (!CollectionUtils.isEmpty(accountIdList)) {
                    communicateClient.sendMsg(new SendMessageDTO("special", accountIdList.toArray(new String[0]),
                            JSONObject.toJSONString(
                                    DataReturn.ok(MsgIdentificationConstants.CANCEL_MEETING, androidHangOffVO))));
                }
            }
            return DataReturn.ok();
        } catch (Exception e) {
            logger.error("安卓端会议取消,e:{}", e);
            return DataReturn.failure(ResultCode.SERVER_ERROR, e.getMessage());
        }
    }

    /**
     * 挂断音视频app端发送消息
     *
     * @throws Exception
     */
    private void hangOffPushAliYunMsg(Set<String> protectorIdList, String msg) throws Exception {
        if (!CollectionUtils.isEmpty(protectorIdList)) {
            AliPushMessagePojo aliPushMessagePojo = AliPushMessagePojo.builder().accountList(
                    new ArrayList<>(protectorIdList))
                    .deviceType(MsgConstants.DEVICE_TYPE_ANDROID)
//                    .pushType(MsgConstants.PUSH_TYPE_NOTICE)
                    .pushType(MsgConstants.PUSH_TYPE_MESSAGE)
                    .target(MsgConstants.TARGET_ACCOUNT)
                    .title("会议挂断通知")
                    .pushContentPojo(new AliPushContentPojo(NoticeTypeConstants.NOTICE_TYPE_HANG_OFF, msg))
                    .build();
            AliyunPushMessageUtils.customizeAdvancedPush(aliPushMessagePojo);
        }
    }

}

